#!/bin/bash

pass()
{
	echo "====PASS: $*"
}

fail()
{
	echo "====FAIL: $*"
}

warn()
{
	echo "====WARN: $*"
}

skip()
{
	echo "====SKIP: $*"
}

prepare_build_repo()
{
	[ "$KERNEL_CI_REPO_BRANCH" == "devel-6.6" ] && {
		yum install -y asciidoc || {
			cat > /etc/yum.repos.d/build.repo <<EOF
[build]
name=build
baseurl=http://8.131.87.1/kojifiles/repos/dist-an23-build/latest/$(uname -m)/
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-ANOLIS
gpgcheck=0
EOF
		}
	}
}

anck_build()
{
	prepare_build_repo
	build_script=$TONE_BM_SUITE_DIR/anck_build.sh
	python $TONE_BM_SUITE_DIR/anck_build.py $build_script
	upload_archives $(find /anck_build/ck-build/outputs -name *.rpm)
	return 0
}

kapi_install_dep_pkg()
{
	dep_pkgs="elfutils elfutils-devel bison flex"
	for pkg in $dep_pkgs; do
		remote_cmd "yum install -y $pkg"
	done 
}

check_kapi()
{
	local reboot_kernel_ret=$1
	if [ "$reboot_kernel_ret" != "0" ]; then
		skip "check_kapi"
		return 1
	fi

	if [ "$KERNEL_CI_REPO_BRANCH" != "devel-5.10" ] && [ "$KERNEL_CI_REPO_BRANCH" != "devel-6.6" ]; then
		skip "check_kapi"
		return 0
	fi


	kapi_test_dir="/tmp/kapi_test"
	kapi_test_log="/tmp/kapi_test.log"

	kapi_install_dep_pkg

	rm -rf $kapi_test_log
	remote_cmd "[ -d $kapi_test_dir ] && rm -rf $kapi_test_dir"
	remote_cmd "mkdir -p $kapi_test_dir"
	remote_cmd "git clone https://gitee.com/anolis/kabi-dw.git $kapi_test_dir/kabi-dw"
	remote_cmd "\"cd $kapi_test_dir/kabi-dw;make\""
	remote_cmd "git clone -b $KERNEL_CI_REPO_BRANCH https://gitee.com/anolis/kabi-whitelist.git $kapi_test_dir/kabi-whitelist"


	vmlinux_new=$(find /anck_build/ck-build/rpmbuild/BUILD/ -name "vmlinux" | grep -v compressed)
	[ -z "$vmlinux_new" ] && {
		debuginfo_rpm=$(find /anck_build/ck-build/rpmbuild/RPMS -name "kernel-debuginfo*" | grep -v "debuginfo-common")
		cd /anck_build/ck-build/rpmbuild/BUILD/
		rpm2cpio $debuginfo_rpm | cpio -dim
		vmlinux_new=$(find /anck_build/ck-build/rpmbuild/BUILD/ -name "vmlinux")
		cd -
		[ -z "$vmlinux_new" ] && {
			echo "check_kapi: Can not found kernel vmlinux"
			fail "check_kapi"
			return 1
		}
	}

	# copy vmlinux to remote
	vmlinuz_path=$(remote_cmd "find /lib/modules -name 'vmlinuz'" | tail -1)
	vmlinuz_dir=$(dirname $vmlinuz_path)
	logger "scp ${vmlinux_new} root@${REMOTE_HOST}:${vmlinuz_dir}"

	# kapi compare
	remote_cmd "$kapi_test_dir/kabi-dw/kabi-dw generate -s ${kapi_test_dir}/kabi-whitelist/kabi_whitelist_$(uname -m) -o kapi_after_$(uname -m) ${vmlinuz_dir}"
	remote_cmd "$kapi_test_dir/kabi-dw/kabi-dw compare -k ${kapi_test_dir}/kabi-whitelist/kabi_dw_output/kabi_pre_$(uname -m) kapi_after_$(uname -m) > $kapi_test_log"

	ls -l $kapi_test_log || {
		echo "Can not found $kapi_test_log"
		fail "check_kapi"
		return 1
	}

	log_file_content=$(cat "$kapi_test_log")

	if [ -s "$kapi_test_log" ]; then
		echo "========show kapi compare result ========="
		#stdout输出全部日志
		echo "$log_file_content"

		# 存储筛选后的内容
		filtered_content=""
		collect_block=false

		while IFS= read -r line; do
			# https://aliyuque.antfin.com/prt6me/web95p/yv4a8wzkpmg3qym5?singleDoc#
			if echo "$line" | grep -q -E "Symbol removed or moved: func--|Changes detected in: func--"; then
				collect_block=true
				filtered_content+="$line\n"
			elif $collect_block; then
				filtered_content+="$line\n"
				# 遇到空行或结束行停止收集
				if [ -z "$line" ] || [[ "$line" =~ ^[[:space:]]*$ ]]; then
					collect_block=false
				fi
			fi
		done < "$kapi_test_log"

		# 文件中存储筛选后内容
		echo -e "$filtered_content" > "$kapi_test_log"
		upload_archives "$kapi_test_log"

		if [ -n "$filtered_content" ]; then
			fail "check_kapi"
			return 1
		fi
	fi
	pass "check_kapi"
	return 0
}

anck_boot_test()
{
	local rpm_build_ret=$1
        if [ "$rpm_build_ret" != "0" ]; then
                skip "boot_kernel_rpm"
                return 1
        fi

	[ -n "$REMOTE_HOST" ] || {
		echo "Error: REMOTE_HOST is not set"
		fail "boot_kernel_rpm"
		return 1
	}

	anck_rpms_dir="/anck_build/ck-build/outputs/0"
	kver_new=$(find $anck_rpms_dir -name kernel-headers*.rpm | \
		head -n 1 | xargs \
		rpm -qp --queryformat="%{VERSION}-%{RELEASE}.%{ARCH}\n")

	remote_check || return 1
	remote_cmd "rm -rf /anck_rpms"
	logger "scp -r $anck_rpms_dir root@$REMOTE_HOST:/anck_rpms"
	remote_cmd "rpm -Uvh --force /anck_rpms/*.rpm"
	remote_cmd "reboot"
	sleep 30

	[ -n "$REBOOT_TIMEOUT" ] || REBOOT_TIMEOUT=600
	wait_time=30
	ret=1
	while [ "$wait_time" -lt "$REBOOT_TIMEOUT" ]
	do
		remote_check | grep -q $kver_new && ret=0 && break
		echo "Still waiting boot..."
		wait_time=$((wait_time + 30))
		sleep 30
	done
	remote_check
	if [ "$ret" -ne 0 ]; then
		echo "Error: failed to boot $kver_new in ${REBOOT_TIMEOUT}s"
		fail "boot_kernel_rpm"
	else
		echo "Succeed to boot new kernel!"
		pass "boot_kernel_rpm"
	fi
	return $ret
}

remote_check()
{
	logger "ping -c 1 $REMOTE_HOST" || return 1
	logger "timeout 5 ssh root@$REMOTE_HOST uname -r" || return 1
	return 0
}

check_dmesg()
{
	local dmesg_info=$(remote_cmd "dmesg -l err -T | grep -v '\/etc\/keys\/x509_'" | grep -v dmesg)
	if ! [ -z "${dmesg_info}" ]; then
		echo "Got err from dmesg"
		return 1
	else
		echo "Check dmesg success."
		return 0
	fi
}

remote_cmd()
{
	logger "ssh root@$REMOTE_HOST $*"
}


show_result()
{
	local case_name=$1
	local m_ret=$2

	if [ $m_ret -ne 0 ]; then
		fail $case_name
	else
		pass $case_name
	fi
}

run()
{
	run_ret=0
	anck_build_dir="/anck_build"
	[ -d "$anck_build_dir" ] || mkdir -p $anck_build_dir
	# remove anck build log before build
	rm -f /tmp/anck_*.log
	# build ANCK
	anck_build

	# check cases result
	caselist="check_Kconfig build_allyes_config build_allno_config build_anolis_defconfig build_anolis_debug_defconfig anck_rpm_build"
	for case in $caselist; do
		# archive build logs
		upload_archives /tmp/anck_${case}.log
		if [ "$KERNEL_CI_REPO_BRANCH" == "devel-4.19" ] && [ "$case" == "check_Kconfig" ]; then
			skip "check_Kconfig"
			continue
    	fi
		tail -n 5 /tmp/anck_${case}.log | grep -q "$case: pass"
		c_ret=$?
		show_result $case $c_ret

		if [ "$case" == "anck_rpm_build" ]; then
			anck_boot_test $c_ret
			check_kapi $?
			c_ret=$?
		fi
		[ "$c_ret" != "0" ] && run_ret=1
	done
	return $run_ret
}

parse()
{
	$TONE_BM_SUITE_DIR/parse.awk
}
